//
//  MSColorAnimate.swift
//  MichaelToy
//
//  Created by MichaelSun on 2017/11/3.
//  Copyright © 2017年 MichaelSun. All rights reserved.
//

import UIKit

class MSColorAnimate {
    
    let fromRGB: (r:CGFloat,g:CGFloat,b:CGFloat,a:CGFloat)
    let toRGB: (r:CGFloat,g:CGFloat,b:CGFloat,a:CGFloat)
    var nowRGB: (r:CGFloat,g:CGFloat,b:CGFloat,a:CGFloat)
    let footRGB: (r:CGFloat,g:CGFloat,b:CGFloat,a:CGFloat)
    let animation: (UIColor) -> Void
    var completion:((Bool) -> Void)? = nil
    var displayLink: CADisplayLink?
    init(withDuration duration: TimeInterval,fromColor:UIColor,toColor:UIColor, animation: @escaping (UIColor) -> Void, completion: ((Bool) -> Void)? = nil) {
        self.fromRGB = MSColorAnimate.getRGB(withColor: fromColor)
        self.toRGB = MSColorAnimate.getRGB(withColor: toColor)
        self.nowRGB = MSColorAnimate.getRGB(withColor: fromColor)
        self.animation = animation
        self.completion = completion
        
        let gapR = toRGB.r - fromRGB.r
        let gapG = toRGB.g - fromRGB.g
        let gapB = toRGB.b - fromRGB.b
        let gapA = toRGB.a - fromRGB.a
        let times = duration * 60
        let footR = gapR / CGFloat(times)
        let footG = gapG / CGFloat(times)
        let footB = gapB / CGFloat(times)
        let footA = gapA / CGFloat(times)
        
        self.footRGB = (footR,footG,footB,footA)
        self.start()
        
        
        
        
    }
    private func start(){
        print(Date())
        if self.displayLink == nil {
            self.displayLink = CADisplayLink(target: self, selector: #selector(self.setNowRGB))
            self.displayLink?.preferredFramesPerSecond = 60
            self.displayLink?.add(to: RunLoop.current, forMode: .commonModes)
        }
        
        self.displayLink?.isPaused = false
    }
    func stop() {
        if self.displayLink != nil {
            self.displayLink?.isPaused = true
        }
    }
    func remove() {
        if self.displayLink != nil {
            self.displayLink?.invalidate()
            self.displayLink = nil
        }
    }
    @objc private func setNowRGB(){
        let rValue = setValue(withValue: nowRGB.r, foot: footRGB.r, maxValue: toRGB.r)
        let gValue = setValue(withValue: nowRGB.g, foot: footRGB.g, maxValue: toRGB.g)
        let bValue = setValue(withValue: nowRGB.b, foot: footRGB.b, maxValue: toRGB.b)
        let aValue = setValue(withValue: nowRGB.a, foot: footRGB.a, maxValue: toRGB.a)
        self.nowRGB = (rValue.value,gValue.value,bValue.value,aValue.value)
        animation(UIColor(red: rValue.value, green: gValue.value, blue: bValue.value, alpha: aValue.value))
        if rValue.isFinish && gValue.isFinish && bValue.isFinish && aValue.isFinish {
            remove()
            if completion != nil{
                completion!(true)
            }
        }
    }
    private func setValue(withValue value: CGFloat, foot: CGFloat, maxValue: CGFloat)->(value: CGFloat, isFinish: Bool){
        if (value == maxValue || foot == 0){
            return (value, true)
        }
        var newValue = value + foot
        var isFinish = false
        
        if foot < 0 {
            if newValue < maxValue {
                newValue = maxValue
                isFinish = true
            }
        }else if foot > 0 {
            if newValue > maxValue {
                newValue = maxValue
                isFinish = true
            }
        }
        return (newValue, isFinish)
        
        
    }
    class func getRGB(withColor color:UIColor) -> (r:CGFloat,g:CGFloat,b:CGFloat,a:CGFloat) {
        var r: CGFloat = 0.0
        var g: CGFloat = 0.0
        var b: CGFloat = 0.0
        var a: CGFloat = 0.0
        let colorComponents = color.cgColor.components
        if colorComponents?.count == 2 {
            r = colorComponents![0]
            g = colorComponents![0]
            b = colorComponents![0]
            a = colorComponents![1]
        }else if colorComponents?.count == 4 {
            r = colorComponents![0]
            g = colorComponents![1]
            b = colorComponents![2]
            a = colorComponents![3]
        }
        return (r,g,b,a)
        
        
    }
    
}
